import type { AudioAnalysisData } from '../store/speechStore'

class AudioAnalyzer {
  private audioContext: AudioContext | null = null
  private analyser: AnalyserNode | null = null
  private source: MediaElementAudioSourceNode | null = null
  private rafId: number | null = null
  private callback: ((data: AudioAnalysisData) => void) | null = null

  onAnalysisData(cb: (data: AudioAnalysisData) => void) {
    this.callback = cb
  }

  connectAudio(audioEl: HTMLAudioElement) {
    this.stopAnalysis()

    const AC: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext
    this.audioContext = new AC()

    this.analyser = this.audioContext.createAnalyser()
    this.analyser.fftSize = 2048

    this.source = this.audioContext.createMediaElementSource(audioEl)
    this.source.connect(this.analyser)
    // 连接到输出以确保正常播放
    this.analyser.connect(this.audioContext.destination)

    this.startLoop()
  }

  private startLoop() {
    if (!this.analyser || !this.audioContext) return

    const freqLen = this.analyser.frequencyBinCount
    const freqData = new Uint8Array(freqLen)
    const timeData = new Uint8Array(this.analyser.fftSize)

    const tick = () => {
      if (!this.analyser || !this.audioContext) return

      this.analyser.getByteFrequencyData(freqData)
      this.analyser.getByteTimeDomainData(timeData)

      // 估算音量与振幅
      let sum = 0
      let maxAmp = 0
      for (let i = 0; i < timeData.length; i++) {
        const v = (timeData[i] - 128) / 128
        sum += Math.abs(v)
        if (Math.abs(v) > maxAmp) maxAmp = Math.abs(v)
      }
      const amplitude = Math.min(maxAmp, 1)
      const volume = Math.min(sum / timeData.length, 1)

      // 估算主频率
      let maxIdx = 0
      let maxVal = 0
      for (let i = 0; i < freqData.length; i++) {
        if (freqData[i] > maxVal) {
          maxVal = freqData[i]
          maxIdx = i
        }
      }
      const frequency = (maxIdx * this.audioContext.sampleRate) / (2 * freqData.length)

      const hasVoiceActivity = volume > 0.02 || amplitude > 0.02

      const data: AudioAnalysisData = {
        volume,
        frequency: Math.round(frequency),
        amplitude,
        hasVoiceActivity,
        timestamp: Date.now()
      }

      if (this.callback) this.callback(data)
      this.rafId = requestAnimationFrame(tick)
    }

    this.rafId = requestAnimationFrame(tick)
  }

  stopAnalysis() {
    if (this.rafId != null) {
      cancelAnimationFrame(this.rafId)
      this.rafId = null
    }
    try {
      this.source?.disconnect()
      this.analyser?.disconnect()
    } catch {}
    this.source = null
    this.analyser = null
    // 挂起上下文以节约资源，但保留播放能力
    try {
      this.audioContext?.suspend()
    } catch {}
  }
}

export const globalAudioAnalyzer = new AudioAnalyzer()